import Ttshitu
import Settings
import re
import random
import requests
import time
from lxml import etree
import json
import os
import time
import sys
import Log,Notify

class DiscuzApi():
	"""DiscuzApi类，支持登录，数据获取等操作"""
	def __init__(self, uname='', pwd=''):
		if len(uname) == 0 or len(pwd) == 0:
			Log.Log().rwitelog('Discuz账号或密码配置错误，请检查Settings脚本', True)
		self.uname = uname
		self.pwd = pwd
		self.sessionReqs = requests.session()
		self.isLogin = False

	def login(self):
		loginurl = Settings.DiscuzConf['loginurl']
		if len(loginurl) == 0:
			Log.Log().rwitelog('登录论坛网址为空，请检查配置文件Settings脚本')
		else:
			html = self.getHtmnl(loginurl).decode()
			sccode = re.search(r'<span id="seccode_(.*?)">', html, re.M|re.I)
			if sccode is None:
				return None
			else:
				sccode = sccode.group(1)
			sccodeurl = Settings.DiscuzConf['succodeurl'] % sccode
			html = self.getHtmnl(sccodeurl).decode()
			sccodesrc = re.search(r'width="100" height="30" src="(.*?)"', html, re.M|re.I)
			if sccodesrc is None:
				return None
			else:
				sccodesrc = Settings.DiscuzConf['baseurl']+sccodesrc.group(1)
			imageContent = self.getHtmnl(sccodesrc)
			filename = self.saveImages(imageContent)
			Log.Log().rwitelog('验证码保存成功：%s' % filename)
			code = self.vierfyCode(filename=filename)
			if code is False:
				Log.Log().rwitelog(self.Ttshitu.errMsg)
				time.sleep(30)
				return None
			else:
				conmand = {"referer": Settings.DiscuzConf['baseurl'],"loginfield": "username","username": self.uname,"password": self.pwd,"questionid": "0","answer": "","seccodehash": sccode,"seccodemodid": "member::logging","seccodeverify": code,"cookietime": "2592000"}
				Log.Log().rwitelog('验证码识别成功：%s' % code)
			xml = self.getHtmnl(Settings.DiscuzConf['loginurlForm'], conmand).decode()
			if self.uname in xml:
				self.isLogin = True
				Log.Log().rwitelog("%s账号登陆成功" % (self.uname))
			else:
				errMsg = xml
				if '抱歉，验证码填写错误' in xml:
					errMsg = '抱歉，验证码填写错误'
				Log.Log().rwitelog('账号登录失败：%s' % errMsg)
			return self.isLogin

				

	def random_captcha_text(self, captcha_size = 10):
		number = ['0','1','2','3','4','5','6','7','8','9']
		alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
		char_set = number + alphabet
		captcha_text = []
		for i in range(captcha_size):
			c = random.choice(char_set)
			captcha_text.append(c)
		captcha_text = ''.join(captcha_text)
		captcha_text = Settings.ImagesDir+captcha_text+'.png'
		self.filename = captcha_text
		return captcha_text

	def vierfyCode(self, filename):
		self.Ttshitu = Ttshitu.Controller(uname=Settings.Ttshitu['uname'], pwd=Settings.Ttshitu['pwd']);
		code = self.Ttshitu.runVerify(filename)
		if code is False:
			return False
		else:
			return code

	def getHtmnl(self, url, data=None):
		user_agent = r'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36'
		headers = {'User-Agnet': user_agent, 'Connection': 'keep-alive', "Referer": Settings.DiscuzConf['baseurl']}
		try:
			if data is None:
				result = self.sessionReqs.get(url, headers=headers)
			else:
				result = self.sessionReqs.post(url, data=data, headers=headers)
			content = result.content
		except Exception as e:
			content = ''.encode()
			Log.Log().rwitelog('请求网址 %s 出错，可能超时' % url)
		return content

	def saveImages(self, content):
		filename = self.random_captcha_text()
		with open(filename,"wb") as f:
			f.write(content)
		return filename

	def runMonitor(self):
		try:
			TimeSleep = sys.argv[1]
		except Exception as e:
			TimeSleep = Settings.TimeSleep
		Log.Log().rwitelog('数据监控系统开启成功 每%s秒做一次查询' % TimeSleep)
		while True:
			try:
				# 如果没有登陆则进行登陆
				if self.isLogin is False:
					Log.Log().rwitelog('您的账号登录已失效或未登录，正在准备进行重新登录')
					self.login()
				# 检查是否有新消息
				self.monitorNotice()

				# 检查是否有新的购买插件
				self.monitorBuys()

				# 判断是否有需要发的通知
				Notify.Notify().run()
			except Exception as e:
				Log.Log().rwitelog('程序运行出错一次，本次检查跳过！')
			time.sleep(int(TimeSleep))

	def monitorNotice(self):
		noticeurl = Settings.DiscuzConf['noticeurl']
		html = self.getHtmnl(noticeurl).decode()
		if self.checkIslogin(html) is True:
			JsonData = self.loadJson('Notice')
			Notify = self.loadJson('Notify')
			html = etree.HTML(html)
			result = html.xpath('//*[@id="cpcontainer"]/div[2]/div/div[1]/div/div/div/ul/li')
			isUpdate = False
			for index in range(len(result)):
				item = result[index]
				times = item.xpath('span/text()')
				times = times[0]
				notice = item.xpath('text()')
				notice = notice[0]
				item = {'time':times, 'notice': notice}
				if (item in JsonData) is False:
					JsonData.append(item)
					Log.Log().rwitelog('通知列表发现新消息：%s 通知时间:%s' % (item['notice'], item['time']))
					Notify.append('''
####您有新的通知消息
>%s
>通知时间：%s
''' % (item['notice'], item['time']));
					isUpdate = True
			if isUpdate is True:
				self.saveJsons('Notice', JsonData)
				Log.Log().rwitelog('通知数据检查完成，已更新相应%s文件' % (self.getJsonUrl('Notice')))
				self.saveJsons('Notify', Notify)
			else:
				Log.Log().rwitelog('通知数据检查完成，本次无更新')
		else:
			Log.Log().rwitelog('本次未进行通知数据检查，因为当前账号未登录')

	def monitorBuys(self):
		buylogurl = Settings.DiscuzConf['buylogurl']
		html = self.getHtmnl(buylogurl).decode()
		if self.checkIslogin(html) is True:
			JsonData = self.loadJson('Buys')
			Notify = self.loadJson('Notify')
			html = etree.HTML(html)
			# 获取价格数据
			prices = html.xpath('//*[@id="cpcontainer"]/div[2]/div/div[1]/div/div/table/tbody/tr/td[2]/span/text()')
			# 获取插件名称
			pluginnames = html.xpath('//*[@id="cpcontainer"]/div[2]/div/div[1]/div/div/table/tbody/tr/td[1]/span[2]/text()')
			# 获取购买者的网站名称
			buyernames = html.xpath('//*[@id="cpcontainer"]/div[2]/div/div[1]/div/div/table/tbody/tr/td[1]/h2/a/text()')
			# 获取购买者的网站网址
			buyerHrefs= html.xpath('//*[@id="cpcontainer"]/div[2]/div/div[1]/div/div/table/tbody/tr/td[1]/h2/a/@href')
			isUpdate = False
			for index in range(len(prices)):
				timeAndOrderids = html.xpath('//*[@id="cpcontainer"]/div[2]/div/div[1]/div/div/table/tbody/tr[%s]/td[1]/text()' % str(index+2))
				# 获取时间
				time  = timeAndOrderids[4].strip()
				# 获取订单号
				orderid  = timeAndOrderids[5].strip()
				# 获取订单价格
				price = prices[index]
				# 获取插件名称
				pluginname = pluginnames[index]
				# 获取购买者的网站名称
				buyername = buyernames[index]
				# 获取购买者的网站网址
				buyerHref = buyerHrefs[index]

				# 创建集合
				item = {'orderid':orderid, 'pluginname': pluginname, 'price': price, 'buyername': buyername, 'buyerHref': buyerHref, 'time': time}
				if (item in JsonData) is False:
					# 创建微信通知模版
					wechatNotify = '''
#### 恭喜插件又成功销售一份
* #####插件名称
    > %s
* #####订单号
    > %s
* #####订单金额
    > %s
* #####购买者
    > [%s](%s)
* #####购买时间
    > %s
''' % (item['pluginname'], item['orderid'], item['price'], item['buyername'], item['buyerHref'], item['time'])
					JsonData.append(item)
					Log.Log().rwitelog('插件销售记录发现新数据：%s 购买时间:%s' % (item['pluginname'], item['time']))
					Notify.append(wechatNotify);
					isUpdate = True
			if isUpdate is True:
				self.saveJsons('Buys', JsonData)
				Log.Log().rwitelog('插件销售数据检查完成，已更新相应%s文件' % (self.getJsonUrl('Buys')))
				self.saveJsons('Notify', Notify)
			else:
				Log.Log().rwitelog('插件销售数据检查完成，本次无更新')
		else:
			Log.Log().rwitelog('本次未进行插件销售数据检查，因为当前账号未登录')


	def checkIslogin(self, html):
		if '<a href="member.php?mod=logging&amp;action=login">登录</a>' in html:
			self.isLogin = False
		return self.isLogin

	def saveJsons(self, t, data):
		JsonData = json.dumps(data)
		filename = self.getJsonUrl(t)
		with open(filename, 'w', encoding='utf8') as file:
			file.write(JsonData)
		return filename

	def getJsonUrl(self, t):
		filename = Settings.JsonDir + "%s.json" % t
		if os.path.exists(Settings.JsonDir) is False:
			os.mkdir(Settings.JsonDir)
		if os.path.isfile(filename) is False:
			with open(filename, 'w', encoding='utf8') as file:
				file.write('[]')
			Log.Log().rwitelog('写入默认初始文件 %s' % (filename))
		return filename

	def loadJson(self, t):
		filename = self.getJsonUrl(t)
		jsonfile = open(filename, 'r+')
		jsonstr = jsonfile.read()
		JsonDta = json.loads(jsonstr)
		return JsonDta






